<template>
  <div ref="container" :class="{'editMode':isEdit}" class="dynamic-container">
    <el-table
      v-if="(listData && listData.length) || isEdit || showTableHeader"
      ref="dynamicEditRef"
      :data="handelTableData(listData)"
      :border="hasBorder"
      :empty-text="emptyText"
      :max-height="tableMaxHeight"
      :row-class-name="rowClassName"
      fit
      element-loading-text="加载中..."
      header-cell-class-name="dynamic-edit-table-cell"
      hightlight-current-row
      @cell-click="cellClick"
      @row-click="rowEdit"
      @select="selectTable"
      @select-all="selectTable"
      @selection-change="onSelectChange"
    >
      <EmptyPlaceholder slot="empty" :empty-text="emptyText" is-border mode="table" style="padding-bottom: 0;" />
      <el-table-column
        v-if="showSelection"
        align="center"
        type="selection"
        width="50"
      />
      <el-table-column
        v-if="showSerial"
        align="left"
        label="序号"
        width="50">
        <template slot="header" slot-scope="scope">
          <div class="dynamic-table-header">
            <span class="label">{{ scope.column.label }}</span>
          </div>
        </template>
        <template slot-scope="scope">
          <div style="padding-left:12px;">{{ scope.$index +1 }}</div>
        </template>
      </el-table-column>
      <template v-for="(settingItem, index) in listSetting">
        <el-table-column
          :key="index"
          :label="settingItem.label"
          v-bind="settingItem.prop || {}"
          :width="settingItem.width || '100px'"
          align="left">
          <template slot="header" slot-scope="scope">
            <div class="dynamic-table-header">
              <span v-if="isEdit && settingItem.isRequired" style="color: #f56c6c;margin-right:4px;">*</span>
              <div class="flex-center">
                <span class="label">{{ scope.column.label }}</span>
                <el-tooltip class="item" placement="top" effect="dark">
                  <div slot="content">{{ settingItem.tip }}</div>
                  <tipIcon v-if="settingItem.tip" is-diy class="ml5"/>
                </el-tooltip>
              </div>
            </div>
          </template>
          <template slot-scope="scope">
            <!-- 编辑模式 -->
            <div
              v-if="scope.row._inEdit"
              :class="[{
                'isError': errorIds.includes(`${settingItem.keyword}${(curPage-1)*perPage + scope.$index}`),
                'isSelect': selectActive === `${settingItem.keyword}$${scope.$index}` && isEdit && isFill,
              }, ...(scope.row._cellClass? scope.row._cellClass[settingItem.keyword] || [] : []) ]"
              style="position: relative;"
              @click="setSelectActive((settingItem.disabled || linkDisabled(scope.row, settingItem))?'':`${settingItem.keyword}$${scope.$index}`, true)"
            >
              <!-- 输入框：字符串 -->
              <template v-if="settingItem.type === 'inputText'">
                <!-- 付款发票调转 -->
                <div v-if="settingItem.keyword === 'invoiceNumber' && isSupplier && scope.row[settingItem.keyword] && linkDisabled(scope.row, settingItem)" class="row-height light-word">
                  <ToolTip :content="scope.row[settingItem.keyword]" class="cell-span" @click.native="toInputVoice(scope.row)"/>
                </div>
                <el-input
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-else-if="((!scope.row.disable || !settingItem.routerJump) && (!settingItem._inEdit || (settingItem.keyword === 'contactPerson' && scope.row.isAdd)) && (settingItem.keyword !== 'contractNum' || !scope.row.id))"
                  v-model="scope.row[settingItem.keyword]"
                  :disabled="settingItem.disabled || linkDisabled(scope.row, settingItem) || scope.row.disable || isKeywordDisabled(scope.row, settingItem.keyword)|| (settingItem.associatedKey && !scope.row[settingItem.associatedKey])|| exitEmptyDisable(scope.row, settingItem)"
                  :maxlength="!settingItem.dynamicFunction?settingItem.maxlength || 50 : settingItem.dynamicFunction(scope.row, settingItem).maxlength"
                  :placeholder="!settingItem.dynamicFunction ? (scope.row.disable ? settingItem.defaultEmpty : settingItem.placeholder) || settingItem.label : settingItem.dynamicFunction(scope.row, settingItem).placeholder"
                  size="small"
                  type="text"
                  class="edit-table-input-text"
                  clearable
                  @blur="inputChange(settingItem.keyword, scope.row, scope.$index)"
                  @input="textInput($event, scope.row, settingItem, scope.$index)"
                />
                <div v-else :class="{'whiteBg': settingItem._inEdit}" class="read-content custom-column">
                  <!-- 付款人状态 -->
                  <div
                    v-if="['status', 'invoiceState'].includes(settingItem.keyword) && typeof scope.row[settingItem.keyword] === 'number'"
                    :class="{'pointer': settingItem.jump}"
                    class="status-content"
                    @click="handleJump(scope.row)">
                    <span :style="{backgroundColor: settingItem.getColor(scope.row[settingItem.keyword])}" class="dot"/>
                    {{ settingItem.statusFilter(scope.row[settingItem.keyword]) }}
                  </div>
                  <!-- 合同编号 -->
                  <div v-if="settingItem.keyword === 'contractNum' && scope.row.id" class="contract-link" @click="toContractDetail(scope.row)">{{ scope.row.contractNum }}</div>
                  <!-- 时间戳 -->
                  <div v-else-if="settingItem.formatTime">
                    {{ scope.row[settingItem.keyword] | format('YYYY/MM/DD HH:mm:ss') }}
                  </div>
                  <el-tooltip v-else-if="scope.row[settingItem.keyword] && !['status', 'contractNum', 'invoiceState'].includes(settingItem.keyword)" class="item" placement="top" effect="dark">
                    <div slot="content" style="max-width: 200px;">{{ scope.row[settingItem.renderKeyword || settingItem.keyword] }}<span v-if="settingItem.unit">{{ settingItem.unit }}</span></div>
                    <router-link
                      v-if="settingItem.routerJump && scope.row.relatedId && scope.row.orderType"
                      :to="{name: setRouterName(scope.row.orderType), params: setRouterParams(scope.row)}"
                      target="_blank"
                      class="overflow ellipsis"
                      style="color:#406EFF; cursor: pointer !important;"
                    >{{ scope.row[settingItem.keyword] }}</router-link>
                    <div v-else class="overflow">
                      {{ scope.row[settingItem.keyword] }}
                      <span v-if="settingItem.unit">{{ settingItem.unit }}</span>
                    </div>
                  </el-tooltip>
                  <div v-else-if="!['status', 'contractNum', 'invoiceState'].includes(settingItem.keyword) || (settingItem.createText && typeof scope.row.invoiceState !== 'number')" style="color: #999">
                    <router-link
                      v-if="settingItem.routerJump && scope.row.relatedId && scope.row.orderType"
                      :to="{name: setRouterName(scope.row.orderType), params: setRouterParams(scope.row)}"
                      target="_blank"
                      class="overflow ellipsis"
                      style="color:#406EFF; cursor: pointer !important;"
                    >--</router-link>
                    <div v-else style="color: #999">--</div>
                  </div>
                </div>
              </template>
              <!-- 输入框：带输入建议 autocomplete -->
              <el-autocomplete
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'autocomplete'"
                v-model="scope.row[settingItem.keyword]"
                :fetch-suggestions="(queryString, cb) => {fetchAutocomplete(queryString, cb, scope.row, settingItem)}"
                :maxlength="settingItem.maxlength"
                placeholder="请输入内容"
                popper-class="autocomplete-popper"
                @select="autocompleteSelect($event, scope.row, settingItem)"
              >
                <template slot-scope="{item}">
                  <div class="flex-center"><span style="flex:1">{{ item.value }}</span><i v-if="settingItem.canDelBtn" class="el-icon-close del-icon" @click.stop="autocompleteDelFn(item)"/></div>
                </template>
              </el-autocomplete>
              <!-- 纯数字 -->
              <template v-if="settingItem.type === 'inputPureNumber'">
                <el-input
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-if="(!scope.row.disable || !settingItem.routerJump) && (!settingItem._inEdit || (settingItem.keyword === 'contactPerson' && scope.row.isAdd))"
                  v-model="scope.row[settingItem.keyword]"
                  :disabled="settingItem.disabled || linkDisabled(scope.row, settingItem) || scope.row.disable || isKeywordDisabled(scope.row, settingItem.keyword) || exitEmptyDisable(scope.row, settingItem)"
                  :maxlength="!settingItem.dynamicFunction?settingItem.maxlength || 50 : settingItem.dynamicFunction(scope.row, settingItem).maxlength"
                  :placeholder="!settingItem.dynamicFunction ? (scope.row.disable ? settingItem.defaultEmpty : settingItem.placeholder) || settingItem.label : settingItem.dynamicFunction(scope.row, settingItem).placeholder"
                  size="small"
                  type="text"
                  class="edit-table-input-text"
                  clearable
                  @blur="inputChange(settingItem.keyword, scope.row, scope.$index)"
                  @input="valToPureNum($event, scope.row, settingItem.keyword, scope.$index)"/>
              </template>
              <!-- 输入框：数字 -->
              <div v-if="settingItem.type === 'inputNumber'" :class="`edit-input-number-${settingItem.keyword}`" style="position:relative;">
                <el-input
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-model="scope.row[settingItem.keyword]"
                  :placeholder="(scope.row.disable ? settingItem.defaultEmpty : settingItem.placeholder) || settingItem.label"
                  :disabled="settingItem.disabled || linkDisabled(scope.row, settingItem) || scope.row.disable || isKeywordDisabled(scope.row, settingItem.keyword)|| exitEmptyDisable(scope.row, settingItem)"
                  :oninput="`
                    if(value>${settingItem.maxnumber || 999999999999}) {value=${settingItem.maxnumber || 999999999999}}
                    else if(${settingItem.isPositiveNumber} && value < 0) {value = null}
                    else if(value<${settingItem.minnumber || -999999999999}) {value=${settingItem.minnumber || -999999999999}}
                    `"
                  type="number"
                  size="small"
                  @blur="inputChange(settingItem.keyword, scope.row, scope.$index)"
                  @change="numberInputChange(scope.row, settingItem.keyword)"
                  @mousewheel.native.prevent
                />
                <span v-if="settingItem.unit" class="unit">{{ settingItem.unit }}</span>
              </div>
              <!-- 非输入框：关联相乘计算框 -->
              <template v-if="settingItem.type === 'associatedNumber'">
                <span class="cell-span">{{ handleReduce(settingItem.associatedKey, scope.row) }}</span>
              </template>
              <!-- 非输入框，关联相减计算 -->
              <template v-if="settingItem.type === 'associatedSubtract'">
                <div :class="{'disabled-style row-height': settingItem.disabled }">
                  <span class="cell-span">{{ handleSubtract(settingItem.subtractKey, scope.row, settingItem.keyword) }}</span>
                </div>
              </template>
              <!-- 非输入框：只显示 -->
              <template v-if="settingItem.type === 'onlyRead'">
                <div :class="{'disabled-style row-height': settingItem.disabled }">
                  <span v-if="settingItem.renderType === 'filter'" class="cell-span">{{ dataFilter(scope.row[settingItem.keyword], settingItem) }}</span>
                  <ToolTip v-else :content="scope.row[settingItem.keyword]" class="cell-span" />
                </div>
              </template>
              <!-- 付款：关联审批 -->
              <template v-if="settingItem.type === 'withdraws'">
                <el-tooltip v-if="getWithDraws(scope).length" :open-delay="800" placement="top" effect="dark">
                  <div slot="content" style="max-width: 200px">
                    <div v-for="(item, index) in getWithDraws(scope)" :key="index" style="cursor:pointer;" @click="toCheck(item)">{{ item.approvalNumber }}</div>
                  </div>
                  <div v-if="getWithDraws(scope).length > 1" class="light-word cell-span">共{{ getWithDraws(scope).length }}个审批单</div>
                  <div v-else class="light-word ellipsis cell-span" @click="toCheckFirst(getWithDraws(scope))">{{ getWithDraws(scope)[0].approvalNumber }}</div>
                </el-tooltip>
                <div v-else class="cell-span">--</div>
              </template>
              <!-- 输入框：百分比 -->
              <el-input
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'inputRate'"
                v-model="scope.row[settingItem.keyword]"
                :placeholder="settingItem.placeholder || settingItem.label"
                :disabled="settingItem.disabled || linkDisabled(scope.row, settingItem) || scope.row.disable || (settingItem.noFirstDisable && scope.$index !== 0)"
                oninput="if(value>999)value=999"
                type="number"
                size="small"
                @change="rateInputChange(scope.row, settingItem.keyword)"
                @mousewheel.native.prevent
              />
              <!-- 城市级联选择 -->
              <three-level-area
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'selectCity'"
                :select-type="settingItem.selectType || 'region'"
                :placeholder="settingItem.placeholder"
                :separator="settingItem.separator"
                :selected-options="handelArr(scope.row[settingItem.keyword])"
                @update:options="threeLevelArea($event, scope.row, settingItem.keyword)" />
              <!-- 下拉选项 -->
              <selectWithoutHttp
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'select'"
                v-model="scope.row[settingItem.keyword]"
                :list-data="settingItem.options || scope.row[`${settingItem.keyword}_dynamic_options`] || []"
                :multiple="settingItem.multiple"
                :collapse-tags="settingItem.collapseTags"
                :disabled="settingItem.disabled || linkDisabled(scope.row, settingItem) || excludeSpecialColumns(scope.row, settingItem.keyword) || (settingItem.associatedKey && !scope.row[settingItem.associatedKey])|| exitEmptyDisable(scope.row, settingItem)"
                :key-name="settingItem.keyName ? settingItem.keyName : 'id'"
                :label-name="settingItem.labelName ? settingItem.labelName : 'name'"
                :popper-append-to-body="appendToBody"
                :allow-create="settingItem.allowCreate"
                :clearable="!settingItem.notShowClear"
                filterable
                @visible-changes="setSelectActive((settingItem.disabled || linkDisabled(scope.row, settingItem))?'':`${settingItem.keyword}$${scope.$index}`, $event, settingItem.disabled || linkDisabled(scope.row, settingItem))"
                @change="selectChange($event, scope.row, settingItem)"
                @changeInfo="selectManualChange(settingItem.keyword, scope.row)"
              />
              <!-- 下拉滚动分页 -->
              <selectWithUserLoad
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'scrollSelect'"
                v-model="scope.row[settingItem.keyword]"
                :ref="`select_${scope.row.orderPrivateId}_${settingItem.keyword}_ref`"
                :default-list="settingItem.options || scope.row[`${settingItem.keyword}_dynamic_options`] || []"
                :loadmore-method="settingItem.loadmoreMethod"
                :extend-params="setExtendParams(scope.row, settingItem)"
                :multiple="settingItem.multiple"
                :disabled="linkDisabled(scope.row, settingItem) || excludeSpecialColumns(scope.row, settingItem.keyword) || (settingItem.associatedKey && !scope.row[settingItem.associatedKey])"
                :key-name="settingItem.keyName ? settingItem.keyName : 'id'"
                :label-name="settingItem.labelName ? settingItem.labelName : 'name'"
                :value-type="settingItem.valueType ? settingItem.valueType : ''"
                :popper-append-to-body="appendToBody"
                :is-dynamic-load="settingItem.isDynamicLoad"
                :hide-select-list="getHideList(scope, settingItem)"
                :clearable="!settingItem.notShowClear"
                :visible-change-data="visibleChangeData"
                :foot="settingItem.foot"
                :show-check-user="settingItem.showCheckUser"
                filterable
                @clear="clear(scope.row, settingItem)"
                @focus="selectFocus(scope.row, settingItem)"
                @change="selectChange($event, scope.row, settingItem, scope.$index)"
                @changeMethod="scrollSelectChangeMethod($event, scope.row, settingItem, scope.$index)"
              />
              <!-- 多级下拉 -->
              <el-cascader
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'cascader'"
                v-model="scope.row[settingItem.keyword]"
                :options="settingItem.options"
                :show-all-levels="settingItem.showAllLevels !== false"
                :props="{
                  value: settingItem.keyName || 'value',
                  label: settingItem.labelName || 'label',
                  emitPath: settingItem.emitPath !== false,
                  multiple: !!settingItem.multiple,
                  checkStrictly: !!settingItem.checkStrictly
                }"
                :disabled="scope.row.disable"
                :clearable="!settingItem.notShowClear"
                filterable
                collapse-tags
                class="cascader-tag"
                style="width: 100%"
                popper-class="dynamic-order-cascader-popper-class"
                @change="handleChange" />
              <!-- 日期选择 -->
              <el-date-picker
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-if="settingItem.type === 'datepicker'"
                v-model="scope.row[settingItem.keyword]"
                :clearable="true"
                :editable="false"
                :append-to-body="appendToBody"
                :type="settingItem.pickerType?settingItem.pickerType:'date'"
                :format="settingItem.pickerFormat?settingItem.pickerFormat:'yyyy/MM/dd'"
                :placeholder="settingItem.placeholder?settingItem.placeholder:'选择日期'"
                :disabled="settingItem.disabled || scope.row.disable|| exitEmptyDisable(scope.row, settingItem) || linkDisabled(scope.row, settingItem)"
                :picker-options="settingItem.pickerOptions"
                value-format="timestamp"
                size="small"
                style="width:100%;"
                @change="datePickerChange($event, scope.row, settingItem)" />
              <!-- 切换 -->
              <div
                v-if="settingItem.type === 'switch'"
                class="select-inner"
                @click="setSelectActive((settingItem.disabled || linkDisabled(scope.row, settingItem))?'':`${settingItem.keyword}$${scope.$index}`, true)">
                <el-switch
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-model="scope.row[settingItem.keyword]"
                  :active-value="1"
                  :disabled="linkDisabled(scope.row, settingItem)"
                  :inactive-value="0"
                  style="margin-left:10px;"
                  @change="changeValue()"/>
              </div>
              <!-- 文件上传 -->
              <div v-if="settingItem.type === 'attachment'" :class="{'disabled-style': settingItem.disabled || exitEmptyDisable(scope.row, settingItem) || linkDisabled(scope.row, settingItem)}" class="attachment-container">
                <uploadFile
                  v-model="scope.row[settingItem.keyword]"
                  :tool-tip="scope.row._toolTip"
                  :is-required="scope.row._required || scope.row.extendRequiredKeys && scope.row.extendRequiredKeys.includes(settingItem.keyword)"
                  :is-edit="isEdit"
                  :disabled="settingItem.disabled || exitEmptyDisable(scope.row, settingItem) || linkDisabled(scope.row, settingItem)"
                  :show-upload-icon="settingItem.uploadIcon"
                  :import-api="settingItem.importApi?settingItem.importApi:'/admin/contract/file/upload'"
                  @changeValue="changeValue()"
                />
              </div>
              <div v-if="settingItem.type === 'multipleAttachment'" class="multiple-attachment-container">
                <upAttachment
                  ref="uploadImg"
                  :file-list="scope.row[settingItem.keyword]"
                  :import-api="'/common/file/upload'"
                  :hide-confirm="true"
                  :hide-clip-up="false"
                  :extend-params="settingItem.extendParams"
                  :is-disabled="settingItem.disabled || scope.row.disable"
                  :table-upload="true"
                  btn-text="上传文件"
                  @upProgress="upProgress(scope.row)"
                  @complateSetData="complateSetData(scope.row, settingItem.keyword, $event)"
                  @removeFileList="removeFileList(scope.row, settingItem.keyword, $event)">
                  <div class="upload-btn">
                    <i v-if="scope.row['uploadLoading']" class="el-icon-loading" style="margin-right:3px;"/>
                    <span class="content">拖拽文件或</span>
                    <span class="content-link">点击上传</span>
                    <img :src="uploadIcon" alt="">
                  </div>
                </upAttachment>
              </div>
              <TagSelect v-if="settingItem.type === 'tagSelect'" v-model="scope.row[settingItem.keyword]" :default-tag-list="settingItem.defaultTagList" :collapse-tags="true" :module-type="settingItem.moduleType"/>
            </div>
            <!-- 只读模式 -->
            <div
              v-else
              :style="settingItem.showType==='price'?{justifyContent: 'flex-end'}:''"
              :class="{
                'isError isRead': errorIds.includes(`${settingItem.keyword}${(curPage-1)*perPage + scope.$index}`),
                'isSelect': selectActive === `${settingItem.keyword}$${scope.$index}` && isFill
              }"
              class="read-content"
              @click="setSelectActive((settingItem.disabled || linkDisabled(scope.row, settingItem))?'':`${settingItem.keyword}$${scope.$index}`, true)">
              <SecretText
                v-if="settingItem.showType==='secret'"
                :log-text="scope.row._logText || settingItem.logText"
                :origin-text="scope.row[settingItem.keyword]" />
              <PriceColumn v-else-if="settingItem.showType==='price'" :real-val="scope.row[settingItem.keyword]" :price="scope.row[settingItem.keyword]" />
              <span v-else-if="settingItem.type === 'datepicker'">{{ scope.row[settingItem.keyword] | format(settingItem.formatStr?settingItem.formatStr:'YYYY/MM/DD') }}</span>
              <uploadFile v-else-if="settingItem.type === 'attachment'" v-model="scope.row[settingItem.keyword]" :is-edit="false" />
              <FileShowList v-else-if="settingItem.type === 'multipleAttachment'" :file-list="scope.row[settingItem.keyword] || []" is-show-single-file />
              <span v-else-if="settingItem.renderType === 'filter'">{{ dataFilter(scope.row[settingItem.keyword], settingItem) }}</span>
              <template v-else-if="settingItem.renderType === 'switch'">
                <el-switch
                  v-model="scope.row[settingItem.keyword]"
                  :active-value="1"
                  disabled/>
              </template>
              <!-- 付款：关联审批 -->
              <template v-else-if="settingItem.type === 'withdraws'">
                <el-tooltip v-if="getWithDraws(scope).length" :open-delay="800" placement="top" effect="dark">
                  <div slot="content" style="max-width: 200px">
                    <div v-for="(item, index) in getWithDraws(scope)" :key="index" style="cursor:pointer;" @click="toCheck(item)">{{ item.approvalNumber }}</div>
                  </div>
                  <div v-if="getWithDraws(scope).length > 1" class="light-word cell-span">共{{ getWithDraws(scope).length }}个审批单</div>
                  <div v-else class="light-word ellipsis cell-span" @click="toCheckFirst(getWithDraws(scope))">{{ getWithDraws(scope)[0].approvalNumber }}</div>
                </el-tooltip>
                <div v-else class="cell-span">--</div>
              </template>
              <!-- 付款发票调转 -->
              <div v-else-if="settingItem.renderType === 'voiceLink'" class="row-height">
                <ToolTip v-if="scope.row[settingItem.keyword]" :content="scope.row[settingItem.keyword]" class="cell-span light-word" @click.native="toInputVoice(scope.row)"/>
                <span v-else>--</span>
              </div>
              <div
                v-else-if="['status', 'invoiceState'].includes(settingItem.keyword) && typeof scope.row[settingItem.keyword] === 'number'"
                :class="{'pointer': settingItem.jump}"
                class="status-content"
                @click="handleJump(scope.row)">
                <span :style="{backgroundColor: settingItem.getColor(scope.row[settingItem.keyword])}" class="dot"/>
                {{ settingItem.statusFilter(scope.row[settingItem.keyword]) }}
              </div>
              <div v-else-if="settingItem.formatTime">
                {{ scope.row[settingItem.keyword] | format('YYYY/MM/DD HH:mm:ss') }}
              </div>
              <div v-else-if="settingItem.isSecret">
                <template v-if="scope.row['showSecret']">
                  {{ scope.row[settingItem.keyword] }}
                </template>
                <template v-else>
                  <span v-if="scope.row[settingItem.keyword].length <= 2">***********</span>
                  <span v-else>{{ `${scope.row[settingItem.keyword][0]}*********${scope.row[settingItem.keyword][scope.row[settingItem.keyword].length - 1]}` }}</span>
                  <el-button type="text" style="color: #406EFF; font-size: 14px" @click="handleCheckSecretVal(scope.row)">点击查看</el-button>
                </template>
              </div>
              <div v-else-if="settingItem.multiple" class="overflow">
                <ToolTip :content="formatTag(scope.row[settingItem.keyword], settingItem.labelName)" />
              </div>
              <TagSelect v-else-if="settingItem.type === 'tagSelect'" v-model="scope.row[settingItem.keyword]" :is-show-edit-btn="settingItem.isShowEditBtn" show-mode="string" mode="detail" @handelClickEdit="$emit('handelClickEdit',scope.row, scope.$index)" />
              <div v-else-if="settingItem.valueType === 'object'">
                <template v-if="scope.row[settingItem.keyword]">
                  {{ scope.row[settingItem.keyword][settingItem.labelName] + `${scope.row[settingItem.keyword][settingItem.foot] || ''}` }}
                </template>
                <template v-else>--</template>
              </div>
              <div v-else-if="settingItem.type === 'associatedSubtract'">
                <span class="cell-span">{{ handleSubtract(settingItem.subtractKey, scope.row, settingItem.keyword) }}</span>
              </div>
              <template v-else>
                <div v-if="scope.row[settingItem.renderKeyword || settingItem.keyword] || scope.row[settingItem.renderKeyword || settingItem.keyword] === 0" class="flex">
                  <el-tooltip class="item" placement="top" effect="dark">
                    <div slot="content" style="max-width: 200px;">{{ scope.row[settingItem.renderKeyword || settingItem.keyword] }}<span v-if="settingItem.unit">{{ settingItem.unit }}</span></div>
                    <router-link
                      v-if="settingItem.routerJump && scope.row.relatedId && scope.row.orderType"
                      :to="{name: setRouterName(scope.row.orderType), params: setRouterParams(scope.row)}"
                      target="_blank"
                      class="overflow ellipsis"
                      style="color:#406EFF"
                    >{{ scope.row[settingItem.renderKeyword || settingItem.keyword] }}</router-link>
                    <div v-else class="overflow ellipsis">
                      {{ scope.row[settingItem.renderKeyword || settingItem.keyword] }}
                      <span v-if="settingItem.unit">{{ settingItem.unit }}</span>
                    </div>
                  </el-tooltip>
                  <div v-if="extendBtn === settingItem.keyword" class="button-text extend-btn" @click="$emit('extendEvent', {scope:scope})">编辑</div>
                </div>
                <div v-else >--</div>
              </template>
            </div>
          </template>
        </el-table-column>
      </template>
      <el-table-column
        v-if="isEdit && (showDeleteBtn || showCopyBtn || isFill)"
        :width="showMobilePage? 80 : isFill || isSupplier? 150 : 100"
        :fixed="fixed"
        :align="operateAlign"
        label="操作"
      >
        <template slot-scope="scope">
          <div @click.stop="()=>{}">
            <!-- <div :class="{'custom-column': scope.row._hiddenDelBtn}" style="padding: 0 10px;"> -->
            <div v-if="!showMobilePage" class="operator-btn" style="padding: 0 10px;">
              <el-button v-if="showDelBtn(scope.row._hiddenDelBtn, scope.row.creator, scope.row.isAdd)" :disabled="canEmpty?false:value.length === 1" type="text" @click="deleteItem(scope.row, preTotal + scope.$index)"><span style="font-size:14px;">删除</span></el-button>
              <el-button v-if="showCopyBtn" type="text" @click="copy(scope.row)"><span style="font-size:14px;">复制</span></el-button>
              <el-button v-if="isFill" type="text" @click="fillContent(scope)"><span style="font-size:14px;">填充</span></el-button>
              <el-button v-if="isSupplier" :disabled="!scope.row.inputInvoiceId" type="text" @click="toEdit(scope)"><span style="font-size:14px;">编辑</span></el-button>
            </div>
            <tableOperateBtn v-else>
              <el-dropdown-item v-if="showDelBtn(scope.row._hiddenDelBtn, scope.row.creator, scope.row.isAdd)" :disabled="canEmpty?false:value.length === 1" @click.native="deleteItem(scope.row, preTotal + scope.$index)">
                <div>删除</div>
              </el-dropdown-item>
              <el-dropdown-item v-if="showCopyBtn" @click.native="copy(scope.row)">
                <div>复制</div>
              </el-dropdown-item>
              <el-dropdown-item v-if="isFill" @click.native="fillContent(scope)">
                <div>填充</div>
              </el-dropdown-item>
              <el-dropdown-item v-if="isSupplier && scope.row.inputInvoiceId" @click.native="toEdit(scope)">
                <div>编辑</div>
              </el-dropdown-item>
            </tableOperateBtn>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <empty-placeholder v-else :empty-text="emptyText" :empty-img="emptyDataIcon" image-size="100px" style="margin-bottom: 24px"/>
    <div v-if="isEdit && showAddBtn" :style="addBtnTop ? 'margin-top:10px;' : ''">
      <!-- <el-button class="submit-btn" size="small" type="primary" @click="addValue">{{ btnText || '添加收款人' }}</el-button> -->
      <div :style="addBtnStyle" class="add-btn" @click="addValue">{{ btnText || '添加收款人' }}&nbsp;<i v-if="showAddIcon" class="el-icon-plus" /> </div>
    </div>
    <div v-if="(!isEdit || openPage) && (listData.length > 10 || listDataCount > 10)" style="margin-top:12px;display:flex;">
      <span style="flex:1"/>
      <el-pagination
        :page-sizes="pageSizes"
        :current-page="currentPage"
        :page-size="pageSize"
        :small="showMobilePage"
        :total="listDataCount>0?listDataCount:listData.length"
        :layout="showMobilePage ? 'prev, pager, next, jumper':'total, prev, pager, next, sizes, jumper'"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"/>
    </div>
  </div>
</template>

<script>
/**
 * 动态编辑表格：listSetting的属性说明
 *
 * @param {string}  label   名称
 * @param {string}  keyword 字段
 * @param {string}  width   宽度
 * @param {boolean}  isRequired   必填
 * @param {string}  type    编辑状态时的类型：inputText(字符串输入框)、inputNumber(数字输入框)、select(不能下拉加载的下拉框)
 * @param {array}  options  下拉选项
 * @param {string}  renderType  只读模式渲染内容方式：filter(根据options列表渲染名称)
 * @param {boolean}  _inEdit  非输入框，且白色背景，鼠标不禁止
 * @param {boolean}  formatTime  时间戳，且需格式化时间
 * @param {string}  importApi  上传组件的文件上传路径
 * @param {boolean}  uploadIcon  上传组件是否需要icon
 * @param {string}  formatStr  时间组件的格式化字符串
 * @param {string}  placeholder  占位提示字符
 * @param {string}  pickerType  时间选择组件类型
 * @param {string}  pickerFormat  时间选择组件格式化字符串
 */

import selectWithoutHttp from '@/components/Common/selectWithoutHttp';
import selectWithUserLoad from '@/components/Common/selectWithUserLoad';
import EmptyPlaceholder from '@/components/Common/emptyPlaceholder';
import ThreeLevelArea from '@/components/ThreeLevelArea';
import upAttachment from '@/components/Common/upAttachment/index';
import FileShowList from '@/components/CreateOrder/fileShowList';
import uploadFile from '@/components/Common/uploadFile';
import TagSelect from '@/components/Common/tagSelect';

import emptyDataIcon from '@/assets/empty-data-icon.png';
import { formatTag } from '@/filters/dept';
import { format } from '@/filters/date';
import tableSelections from '@/mixins/tableSelections';
import mobileTable from '@/mixins/mobileTable';
import { hasRouteAuth } from '@/utils/permission';
import { showModal } from '@/utils/message';
import uploadIcon from '@/assets/icon-upload-blue.png';
import { encryption } from '@/utils';

export default {
  components: {
    selectWithoutHttp,
    selectWithUserLoad,
    EmptyPlaceholder,
    ThreeLevelArea,
    uploadFile,
    FileShowList,
    upAttachment,
    TagSelect
  },
  filters: {
    format
  },
  directives: {
    cellFocus: {
      inserted(el, binding) {
        if (binding.value.label === binding.value.currentLabel) {
          el.querySelector('.el-input__inner') && el.querySelector('.el-input__inner').focus();
        }
      }
    }
  },
  mixins: [tableSelections, mobileTable],
  model: {
    prop: 'value',
    event: 'changeValue'
  },
  props: {
    value: {
      type: Array,
      default: () => {
        return [];
      }
    },
    listData: {
      type: Array,
      default: () => {
        return [];
      }
    },
    listDataCount: { // 有数据总条数，则分页为后端分页，前端请求数据
      type: Number,
      default: 0
    },
    listSetting: {
      type: Array,
      default: () => {
        return [];
      }
    },
    btnText: {
      type: String,
      default: ''
    },
    addBtnStyle: {
      type: Object,
      default: null
    },
    showSerial: {
      type: Boolean,
      default: true
    },
    showSelection: {
      type: Boolean,
      default: false
    },
    isEdit: {
      type: Boolean,
      default: false
    },
    showDeleteBtn: {
      type: Boolean,
      default: true
    },
    showAddBtn: {
      type: Boolean,
      default: true
    },
    addBtnTop: {
      type: Boolean,
      default: true
    },
    showCopyBtn: {
      type: Boolean,
      default: true
    },
    isFill: { // 填充功能
      type: Boolean,
      default: false
    },
    appendToBody: { // 填充功能
      type: Boolean,
      default: true
    },
    canEmpty: { // 是否允许为空
      type: Boolean,
      default: false
    },
    showAddIcon: {
      type: Boolean,
      default: true
    },
    defaultParams: {
      type: Object,
      default: () => {
        return {};
      }
    },
    specialColumn: {
      type: Array,
      default: () => []
    },
    orderPrivateId: { // 手动添加订单标识符
      type: Number,
      default: 1
    },
    disableValidKeys: {
      type: Array,
      default: () => []
    },
    hasBorder: { // 表格是否需要边框
      type: Boolean,
      default: true
    },
    emptyText: { // 无数据提示语
      type: String,
      default: '暂无数据'
    },
    showTableHeader: { // 没有数据时是否展示表头
      type: Boolean,
      default: false
    },
    tableMaxHeight: { // 列表最大高度
      type: [String, Number],
      default: null
    },
    nonCopyKey: { // 复制行时过滤项
      type: Array,
      default: () => []
    },
    copyToNextRow: {
      type: Boolean,
      default: false
    },
    customPageTurn: {// 是否自定义翻页
      type: Boolean,
      default: false
    },
    curPage: {
      type: Number,
      default: 1
    },
    perPage: {
      type: Number,
      default: 20
    },
    rowDelAuth: { // 每行的删除是否需要权限，联系/付款人传true
      type: Boolean,
      default: false
    },
    rowDelAuthStr: { // 删除权限字符串
      type: String,
      default: ''
    },
    delTipStr: { // 删除提示语
      type: String,
      default: ''
    },
    extendBtn: { // 文本内容，扩展按钮
      type: String,
      default: ''
    },
    openPage: {
      type: Boolean,
      default: false
    },
    initPageSize: {
      type: Number,
      default: 10
    },
    customValidKey: {// 3.0.2批量新增收入项，选择某项数据去校验其他项 validKey：需要校验的id（associatedKey存在才校验），associatedKey：所关联的id，对象数组的形式传参
      type: Array,
      default: () => []
    },
    pageSizes: {
      type: Array,
      default() {
        return [10, 30, 50, 100, 250, 500];
      }
    },
    visibleChangeData: { // 下拉框出现时是否重新请求数据（前提：列表数据为空）
      type: Boolean,
      default: false
    },
    fixed: {// 操作列浮动设置
      type: [String, Boolean],
      default: 'right'
    },
    currentWidthdraw: { // 当前选中的审批记录
      type: Object,
      default: () => {
        return {
          id: 0,
          examineStatus: 2
        };
      }
    },
    isSupplier: {// 付款申请
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      emptyDataIcon,
      uploadIcon,
      errorIds: [],
      currentPage: 1,
      pageSize: this.initPageSize || 10,
      selectActive: '',
      selectedList: [], // 已选中的列表
      currentUser: this.$store.getters.userName, // 当前登录用户
      ids: '', // 列表当前选中的id
      idKey: 'orderPrivateId',
      tableRefName: 'dynamicEditRef',
      firstInitPanel: true,
      currentLabel: ''
    };
  },
  computed: {
    showDelBtn() {
      return function(_hiddenDelBtn, creator, isAdd) {
        /* 显示删除：
        不为付款/联系人时：显示删除且该行不隐藏删除按钮；
        为付款/联系人时：该条为自己创建 或 有权限 或 为添加的付款/联系人*/
        return (!this.rowDelAuth && (this.showDeleteBtn && !_hiddenDelBtn)) || (this.rowDelAuth && (creator === this.currentUser || this.hasRouteAuth(this.rowDelAuthStr) || isAdd));
      };
    },
    preTotal() { // 当前页之前的条数总和
      return this.customPageTurn ? (this.curPage - 1) * this.perPage : (this.currentPage - 1) * this.pageSize;
    }
  },
  methods: {
    hasRouteAuth,
    formatTag,
    clearError() {
      this.errorIds = [];
    },
    validate() {
      // 验证必填项
      return new Promise((resolve, reject) => {
        const dataList = this.value;
        const requiredKeys = this.listSetting.map(i => {
          if (i.isRequired) {
            return i.keyword;
          }
        }).filter(i => !!i);

        let isOk = true;
        const errorIds = [];
        if (dataList && dataList.length > 0) {
          dataList.forEach((i, index) => {
            if (Array.isArray(requiredKeys) && requiredKeys.length) {
              const requiredKeyList = !i.customizeState && i.disable ? this.disableValidKeys : requiredKeys;
              requiredKeyList.forEach((j, jindex) => {
                if ((!i[j] && i[j] !== 0) || (Array.isArray(i[j]) && i[j].length === 0)) {
                  errorIds.push(`${j}${index}`);
                  isOk = false;
                }
              });
            }
            if (Array.isArray(this.customValidKey) && this.customValidKey.length) { // 关联校验
              const requiredKeyList = this.customValidKey;
              requiredKeyList.forEach((j, jindex) => {
                if (i[j.associatedKey] && !i[j.validKey]) {
                  errorIds.push(`${j.validKey}${index}`);
                  isOk = false;
                }
              });
            }
            if (Array.isArray(i.extendRequiredKeys) && i.extendRequiredKeys.length) {
              i.extendRequiredKeys.forEach((k) => {
                if ((!i[k] && i[k] !== 0) || (Array.isArray(i[k]) && i[k].length === 0)) {
                  errorIds.push(`${k}${index}`);
                  isOk = false;
                }
              });
            }
            if (i._required) {
              if ((!i[i._required] && i[i._required] !== 0) || JSON.stringify(i[i._required]) === '{}') {
                errorIds.push(`${i._required}${index}`);
                isOk = false;
              }
            }
          });
        }
        this.errorIds = errorIds;
        if (isOk) {
          resolve(true);
        } else {
          reject(false);
        }
      });
    },
    // 根据字段来设置是否可填写
    linkDisabled(item, settingItem) {
      if (settingItem.linkDisabled) {
        if (Array.isArray(settingItem.linkDisabled)) {
          const b = settingItem.linkDisabled.some(i => {
            return item[i];
          });
          return b;
        }
        return (settingItem.linkDisabled ? !!item[settingItem.linkDisabled] : false);
      }
      return false;
    },
    setExtendParams(rowData, settingItem) {
      if (rowData['CUSTOM_EXTEND_PARAMS']) {
        return Object.assign(rowData['CUSTOM_EXTEND_PARAMS'], settingItem.extendParams);
      }
      return settingItem.extendParams || {};
    },
    excludeSpecialColumns(data, key) {
      if (!data || !data.disable) return false;
      return !this.specialColumn.includes(key);
    },
    selectFocus(rowData, settingItem) {
      // 多选时防止每次选中都重新请求接口
      if (!this.firstInitPanel && settingItem.multiple) {
        this.firstInitPanel = true;
        return;
      }
      const refName = `select_${rowData.orderPrivateId}_${settingItem.keyword}_ref`;
      this.$emit('selectFocus', settingItem.keyword, rowData);
      this.$nextTick(() => {
        settingItem.isDynamicLoad && this.$refs[refName][0].getListData();
      });
    },
    clear(item, settingItem) {
      if (settingItem.keyword === 'proposerName') {
        if (item.proposer) item.proposer = null;
        if (item.userName) item.userName = '';
        if (item.proposerName) item.proposerName = '';
      }
      this.$emit('clear', { item: item, key: settingItem.keyword });
      this.changeValue();
    },
    selectChange(e, item, settingItem, rowIndex) {
      settingItem.multiple && (this.firstInitPanel = false);
      if (item.isAuto && settingItem.linkField) {
        const data = settingItem.options.find(i => i.id === e);
        if (data)item[settingItem.linkField] = data[settingItem.linkField];
      }
      this.$emit('selectChange', { item: item, key: settingItem.keyword, rowIndex: rowIndex });
      this.changeValue();
    },
    selectManualChange(key, data) {
      this.$emit('selectManualChange', { key, item: data });
    },
    scrollSelectChangeMethod(data, row, settingItem, rowIndex) {
      if (data) {
        const rowData = JSON.parse(JSON.stringify(data));
        rowData.orderPrivateId = row.orderPrivateId;
        settingItem.renderKeyword && this.$set(row, settingItem.renderKeyword, data[settingItem.labelName]);
        this.$emit('scrollSelectChange', settingItem.keyword, rowData, rowIndex, settingItem);
      } else {
        this.$emit('scrollSelectClear', settingItem.keyword, row);
      }
    },
    datePickerChange(value, rowData, settingItem) {
      this.changeValue();
      this.$emit('datePickerChange', { item: rowData, key: settingItem.keyword });
    },
    changeValue(value = null) {
      this.$emit('changeValue', value || this.value);
      this.errorIds = []; // 重制红框
      this.$emit('onSelectChange', this.selectedList);
    },
    changeInputNumberData(item, key) {
      this.$emit('changeInputNumberData', { item: item, key: key });
    },
    dataFilter(rowData, settingItem) {
      if ((rowData || rowData === 0) && settingItem && settingItem.options) {
        const obj = settingItem.options.find(i => Number(i.id) === Number(rowData));
        return obj ? obj[settingItem.renderKeyword || 'name'] : '--';
      }
      return '--';
    },
    toContractDetail(row) {
      const url = this.$router.resolve({
        name: 'contractDetail',
        params: {
          id: encryption(row.id)
        },
        query: {
          processId: encryption(row.processId)
        }
      });
      window.open(url.href, '_blank');
    },
    textInput(e, data, settingItem, index) {
      if (settingItem.needTrim) {
        data[settingItem.keyword] = e.trim();
      }
      this.changeValue();
    },
    inputChange(key, data, index) {
      this.$emit('inputChange', { key, data, index });
    },
    valToPureNum(text, row, key, index) {
      if (row[key]) row[key] = text.replace(/[^\d]/g, '');
      this.changeValue();
    },
    rateInputChange(row, key) {
      if (row[key]) row[key] = Number(row[key]).toFixed(3);
      this.changeInputNumberData(row, key);
      this.changeValue();
      this.$emit('rateInputChange', row, key);
    },
    numberInputChange(row, key) {
      if (row[key]) row[key] = Number(row[key]).toFixed(2);
      this.changeValue();
      this.changeInputNumberData(row, key);
    },
    // 多选
    tableSelectionChange(e) {
      this.ids = e.map(item => item[this.idKey]).join();
    },
    handelTableData(listData) {
      if (this.openPage) {
        return this.handleData(listData);
      }
      if (this.isEdit || this.listDataCount) {
        if (this.customPageTurn) {
          return this.handleCustomPageTurn(listData);
        } else {
          return this.value;
        }
      } else {
        return this.handleData(listData);
      }
    },
    // 翻页
    handleData(tableData = []) {
      const totalPage = Math.ceil(tableData.length / this.pageSize);
      if (this.currentPage > totalPage && this.currentPage > 1) {
        this.currentPage--;
      }
      const pageData = tableData.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize);
      this.setSelectRow && this.setSelectRow(pageData);
      return pageData;
    },
    // 自定义翻页
    handleCustomPageTurn(tableData) {
      const pageData = tableData && tableData.slice((this.curPage - 1) * this.perPage, this.curPage * this.perPage) || [];
      this.setSelectRow && this.setSelectRow(pageData);
      return pageData;
    },
    handleSizeChange(val) {
      if (this.listDataCount > 0) {
        this.$emit('handleSizeChange', val);
      } else {
        this.pageSize = val;
      }
    },
    handleCurrentChange(val) {
      if (this.listDataCount > 0) {
        this.$emit('handleCurrentChange', val);
      } else {
        this.currentPage = val;
      }
    },
    addValue(isFlashback = false, extendParams = {}) {
      let params = {};
      if (this.defaultParams) {
        params = { ...this.defaultParams, ...extendParams };
      }
      this.toReadModel();// 取消编辑态
      params._inEdit = true;
      this.listSetting.forEach(i => {
        if (i.default || i.default === 0) {
          params[i.keyword] = i.default;
        }
      });
      params.orderPrivateId = this.orderPrivateId + 1;
      this.$emit('orderPrivateIdChange', this.orderPrivateId + 1);
      isFlashback ? this.value.unshift(params) : this.value.push(params);
      this.changeValue();
    },
    deleteItem(item, index) {
      // item.isAdd 新增行的删除，不需要弹框提示
      if (this.appendToBody && !item.isAdd) {
        const tip = this.rowDelAuth ? this.delTipStr : '是否确定删除？';
        showModal(tip, '', {
          center: true,
          showClose: true
        }).then(() => {
          if (this.rowDelAuth) { // 付款/联系人里的删除
            this.value[index].deleted = 1;
            this.$emit('delRowData', this.value[index]);
            this.value.splice(index, 1);
            this.changeValue();
          } else {
            this.value.splice(index, 1);
            this.changeValue();
            this.$emit('onRowDel', item);
          }
        });
      } else {
        this.value.splice(index, 1);
        this.changeValue();
      }
    },
    reloadScrollSelectData(curSelectPrivateId, curKeyword) {
      if (!curSelectPrivateId || !curKeyword) return;
      const refName = `select_${curSelectPrivateId}_${curKeyword}_ref`;
      setTimeout(() => {
        this.$refs[refName][0].getListData();
      });
    },
    copy(item) {
      const copyData = JSON.parse(JSON.stringify(item));
      if (copyData.id || copyData.id === 0) delete copyData.id;
      copyData.disable && delete copyData.disable;
      copyData.customizeState = true;
      copyData.orderPrivateId = this.orderPrivateId + 1;
      this.nonCopyKey.forEach(key => {
        delete copyData[key];
      });
      this.$emit('orderPrivateIdChange', this.orderPrivateId + 1);
      this.$emit('copyItem', item);
      this.toReadModel();
      this.$set(copyData, '_inEdit', true);
      if (this.copyToNextRow) {
        const rowIndex = this.value.findIndex(valueItem => valueItem.orderPrivateId === item.orderPrivateId);
        this.value.splice(rowIndex + 1, 0, copyData);
      } else {
        this.value.push(copyData);
      }
      this.changeValue();
    },
    /** 填充功能 */
    fillContent(scope) {
      if (this.selectActive && this.value.length > 1) {
        const key = this.selectActive.split('$')[0];
        const settingItem = this.listSetting.find(i => i.keyword === key) || {};
        const index = Number(this.selectActive.split('$')[1]);
        const item = this.value[index];
        if (key && (item[key] || item[key] === 0)) {
          this.value.forEach((i) => {
            if (!(settingItem.disabled || this.linkDisabled(i, settingItem)) && (!i.disable || (i.disable && this.specialColumn.includes(settingItem.keyword)))) {
              this.$set(i, key, item[key]);
            }
          });
          this.changeValue();
        }
      }
    },
    rowClassName(data) {
      return data.row._inEdit ? 'edit-mode' : 'read-mode';
    },
    // 行编辑
    rowEdit(row) {
      this.toReadModel();
      this.$set(row, '_inEdit', true);
      this.$refs['container'].style.width = `${this.$refs['container'].offsetWidth + 0.01}px`;
      this.changeValue();
    },
    toReadModel() {
      this.value.map(i => {
        i._inEdit = false;
      });
    },
    // 点击单元格获取焦点
    cellClick(row, column, cell, event) {
      this.currentLabel = column.label;
    },
    toEdit(scope) {
      this.$emit('toEdit', scope);
    },
    toInputVoice(row = {}) {
      const url = this.$router.resolve({
        name: 'inputInvoiceDetail',
        query: { id: row.inputInvoiceId }
      });
      window.open(url.href, '_blank');
    },
    setSelectActive(name, isSet) {
      if (isSet) this.selectActive = name;
    },
    // 选择城市
    threeLevelArea(data, item, key) {
      item[key] = data.join(',');
      this.changeValue();
    },
    handelArr(data) {
      if (!data) return [];
      if (typeof data === 'string') {
        return data.split(',');
      } else {
        return data;
      }
    },
    handleChange(val) {
      // console.log(val);
    },
    // 表格勾选中
    onSelectChange(data) {
      this.selectedList = data;
      this.$emit('onSelectChange', data);
    },
    // 跳转订单详情页
    setRouterName(type) {
      return type === 1 ? 'orderDetail' : type === 2 ? 'projectDetail' : 'projectChildDetail';
    },
    setRouterParams(data) {
      const { orderType, relatedId } = data;
      const key = orderType === 1 ? 'orderId' : 'id';
      return { [key]: relatedId };
    },
    isKeywordDisabled(item, key) {
      if (item._disabledObj) {
        return item._disabledObj[key];
      }
      return false;
    },
    exitEmptyDisable(row = {}, settingItem) {
      if (!settingItem.associatedKeys) return false;
      const keys = settingItem.associatedKeys || [];
      const isEmptyArr = [];
      keys.forEach(key => {
        if (row[key] || row[key] === 0) {
          isEmptyArr.push(false);
        } else {
          isEmptyArr.push(true);
        }
      });
      return !isEmptyArr.every(i => i === false);
    },
    /**
     * 事件
     */
    fetchAutocomplete(value, cb, item, settingItem) {
      this.$emit('fetchAutocomplete', { value, cb, item, settingItem });
    },
    autocompleteSelect(value, item, settingItem) {
      this.$emit('autocompleteSelect', { value, item, settingItem });
    },
    handleCheckSecretVal(rowData) {
      this.$emit('handleCheckSecretVal', rowData);
    },
    /** 附件上传 */
    upProgress(row) {
      this.$set(row, 'uploadLoading', true);
    },
    complateSetData(row, key, { data, fileName }) {
      row['uploadLoading'] = false;
      const fileList = {
        name: fileName,
        url: data.url,
        time: new Date().getTime()
      };
      if (typeof data === 'string') {
        fileList.url = data;
      } else {
        fileList.url = data.url;
      }
      if (row[key]) {
        row[key].push(fileList);
      } else {
        this.$set(row, key, [fileList]);
      }
    },
    removeFileList(row, key, { file, index }) {
      row[key].splice(index, 1);
    },
    toCheck(item) {
      const url = this.$router.resolve({
        name: 'supplierDetail',
        query: {
          settleId: item.settleId,
          id: item.id,
          isSettle: true,
          fromInputInvoice: 1
        }
      });
      window.open(url.href, '_blank');
    },
    toCheckFirst(withdraws) {
      if (withdraws && withdraws.length > 0) {
        this.toCheck(withdraws[0]);
      }
    },
    getWithDraws(scope) {
      let withdraws = scope.row.withdraws || [];
      withdraws = withdraws.filter(item => item.id !== this.currentWidthdraw.id);
      return withdraws;
    },
    handleReduce(key, data) {
      return key.reduce((a, b) => {
        return data[a] * data[b];
      });
    },
    handleSubtract(key, data, keyword) {
      return key.reduce((a, b) => {
        const res = ((data[a] || 0) - (data[b] || 0)).toFixed(2);
        data[keyword] = res;
        if (!this.isEdit) {
          this.$emit('changeValue', this.value);
        }
        return res;
      });
    },
    getHideList(scope, settingItem) {
      if (settingItem.multiple) {
        return scope.row.associateList;
      }
      if (scope.row[`${settingItem.keyword}_hideList`]) {
        return scope.row[`${settingItem.keyword}_hideList`];
      }
      if (settingItem.valueType === 'object') {
        return [{ ...scope.row[settingItem.keyword] }];
      }
      return [{ [settingItem.keyName]: scope.row[settingItem.keyword], [settingItem.labelName]: (scope.row[settingItem.labelName] || '') }];
    },
    // 输入建议删除事件
    autocompleteDelFn(item, tip = '是否确认删除该条记录') {
      showModal(tip, '', {
        center: true,
        showClose: true
      }).then(() => {
        this.$emit('autocompleteDelFn', item);
      }).catch(_ => {
        return false;
      });
    },
    handleJump(row) {
      this.$emit('handleJump', row);
    }
  }
};
</script>
<style lang="scss" scoped>
.cascader-tag {
  &::v-deep {
    .el-tag {
      color: #406eff;
      background: #eff3fb;
    }
  }
}
.width240 {
  width: 240px;
  & ::v-deep {
    .el-input__inner {
      width: 240px;
    }
  }
}
.light-word {
  color: #406eff;
  cursor: pointer;
}
.flex {
  display: flex;
  align-items: center;
  width: 100%;
}
.read-content {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: 100%;
  height: 100%;
  padding-left: 8px;
  .overflow {
    display: inline;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.custom-column {
  width: 100%;
  background-color: #f5f7fa;
  height: 48px;
  cursor: not-allowed;
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  align-items: center;
}
.read-content-operate{
  width: 100%;
}
.whiteBg {
  background-color: #fff;
  cursor: auto;
}
.add-btn {
  width: 100%;
  height: 48px;
  border: 1px dashed #406EFF;
  border-radius: 4px;
  font-size: 16px;
  font-weight: 500;
  color: #406EFF;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  &:hover {
    background-color: #4063ff !important;
    color: #fff !important;
  }
}
.unit {
  position: absolute;
  top: 50%;
  right: 5px;
  user-select: none;
  transform: translate(0, -50%);
}
.dynamic-container {
  margin-top: 15px;
  .dynamic-table-header {
    display:flex;align-items:center;
    .label {
      color: #141C3D;
      font-weight: 600;
    }
  }
  &::v-deep {
    tr {
      cursor: pointer;
    }
    .threee-level-area-wrap .el-input__inner{
      width: 100%;
    }
    .el-table__body tr:hover>td.el-table__cell {
      background-color: transparent;
    }
    .el-cascader-menu__wrap {
      height: unset !important;
      max-height: 204px !important;
    }
    .dynamic-edit-table-cell {
      background: #F9F9F9;
    }
    .el-table__body tr.hover-row>td.el-table__cell {
      background-color: transparent;
    }
    .el-table__fixed {
      &::before {
        background-color: transparent;
      }
    }
    .el-table__fixed-right {
      &::before {
        background-color: transparent;
      }
    }
    .el-table--border::after {
      background-color: transparent;
    }
    .el-table {
      border-color: transparent;
      &::before {
        background-color: transparent;
      }
      // .el-table__body-wrapper {
      //   padding-bottom: 7px;
      // }
      thead {
        th.dynamic-edit-table-cell {
          &:last-child {
            border-right-color: transparent;
          }
          &:nth-last-child(2) {
            border-right-color: transparent;
          }
        }
      }
      .is-scrolling-none {
        .el-table__empty-block {
          width: 100% !important;
        }
      }
      .el-table__empty-text {
        width: 100%;
      }
      tbody {
        tr {
          td:last-child {
            border-right-color: transparent;
          }
        }
        .el-table__row {
          &:last-child {
            td {
              border-bottom: 1px solid #EBEEF5;
            }
          }
        }
      }
    }
    .el-date-table,.el-year-table,.el-month-table {
      th {
        border-right: none;
      }
    }
    .el-date-table td {
      padding: 4px 0 !important; border: none !important;
    }
    .el-year-table td {
      padding: 20px 3px !important; border: none !important;
    }
    .el-month-table td {
      padding: 8px 0 !important; border: none !important;
    }
  }
  &.editMode {
    &::v-deep {
      .el-select__caret {
        color: #333;
      }
      .el-table__row {
        td {
          padding: 0;
        }
        .cell {
          padding: 0;
          .el-input__inner {
            height: 48px;
            border-radius: 0;
            border-color: transparent;
          }
        }
      }
      .el-select, .el-autocomplete, .el-cascader {
        width: 100%;
      }
    }
  }
}
.select-inner {
  border: 1px solid transparent;
  height: 48px;
  display: flex;
  align-items: center;
}
.isSelect {
  &::v-deep {
    .el-input__inner {
      border-color: #406EFF !important;
    }
  }
  .select-inner {
    border-color: #406EFF !important;
  }
}
.isRead{
  border:1px solid red;
}
.isError {
  &::v-deep {
    .el-table__row{
      td{
        border:1px solid red !important;
      }
    }
    .el-input__inner {
      border-color: red !important;
    }
    .attachment-container{
      border:1px solid red;
    }
  }
}
.attachment-container {
  width: 100%;
  height: 57px;
  display: flex;
  align-items: center;
  background-color: #fff;
}
.status-content{
  display: flex;
  align-items: center;
}
.dot {
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  margin-right: 6px;
}
.disabled-style {
  cursor: not-allowed;
  background-color: #F5F7FA;
  color: #C0C4CC;
}
.row-height {
  display: flex;
  align-items: center;
  height: 48px;
}
.multiple-attachment-container {
  padding: 10px;
  background-color: #fff;
  min-height: 48px;
  .upload-btn {
    display: flex;
    align-items: center;
    .content {
      color: #dddddd;
    }
    .content-link {
      color: #406EFF;
    }
    img {
      width: 16px;
      margin-left: 4px;
    }
  }
  & ::v-deep {
    .fb-upload-container, .file-container, .fb-up-attachment {
      width: auto;
      max-width: 240px;
    }
    .file-container {
      max-height: 50px;
      overflow-y: auto;
    }
  }
}
.extend-btn {
  flex-shrink: 0;
  margin-left: 4px;
  margin-right: 4px;
}
.cell-span {
  padding: 0 8px;
}
.del-icon{
  font-size: 14px;
  margin-left: 8px;
  cursor: pointer;
}
.del-icon:hover {
  color: #406EFF;
}
.operator-btn {
  &::v-deep {
    .el-button--text:not(:first-child) {
      position: relative;
      &::before {
        content: '';
        width: 1px;
        height: 12px;
        position: absolute;
        left: -6px;
        top: 1px;
        background-color: #ddd;
      }
    }
  }
}
.pointer {
  cursor: pointer;
}
</style>
<style lang="scss">
.autocomplete-popper {
  width: auto !important;
}
.dynamic-order-cascader-popper-class {
  &::v-deep {
    .el-input {
      width: 250px;
    }
    .el-cascader-panel .el-cascader-menu__wrap {
      height: unset !important;
      max-height: 204px;
    }
  }
}
.el-date-picker__time-header {
  .el-time-panel__footer {
    padding-right: 50px;
  }
}
.contract-link {
  color: #406eff;
  cursor: pointer;
  position: absolute;
  z-index: 999;
}
.edit-mode,.read-mode{
  td {
    height: 49px !important;
    padding: 0 !important;
  }
  .cell:first-child{
    padding: 0 !important;
  }
}
.edit-mode {
  td:first-child {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .el-select__caret {
    color: #333 !important;
  }
  .cell {
    padding: 0 ;
    .el-input__inner {
      height: 49px !important;
      border-radius: 0 !important;
      border-color: transparent;
    }
  }
}
.read-mode{
  td:first-child{
    display: flex;
    justify-content: center;
  }
  .cell {
    display: flex;
    align-items: center;
    padding: 0 ;
    height: 49px !important;
  }
}
</style>
